home *** CD-ROM | disk | FTP | other *** search
- RED segment para public 'code'
- assume cs:red, ds:red, es:red, ss:nothing
- org 100h ;.com format
- begin:
- jmp code_start ; jump around data declarations
- declare: ; messages, storage areas, equates
- copyright db 'REDirect (C) 1985, Dickinson Associates Inc.'
- db 13,10,'$'
- path_file_len equ 77 ;length=1, path=63, filename=12, 0=1
- source_file db path_file_len dup (0)
- target_path db path_file_len dup (0)
- source_end dw 0
- target_end dw 0
- pc_dos_ver db 0
- valid_in db 'abcdefghijklmnopqrstuvwxyz,;=',9
- valid_out db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',4 DUP(32)
- valid_num equ $ - valid_out + 1
- err_flag db 0
- err_head db 10,13,'REDirect Error - $'
- bad_version db 'Incorrect PC-DOS Version$'
- no_parms db 'Correct Syntax is:',13,10,10
- db 'RED [d:][source_path]source_filename[.ext] [d:][target_path]$'
- file_not_found db 'File not Found$'
- path_not_found db 'Target Path not Found$'
- pc_dos_2_patch db 13,10,'or $'
- drives_conflict db 'Source and Target Disk Drives Conflict$'
- undefined_err db 'Undefined Error: PC-DOS Function 56H$'
- err_tail db 10,10,13,' . . . Aborting',10,13,13,'$'
- good_msg db ' . . REDirected to . . $'
- bad_msg1 db ' . . Not REDirected . . $'
- bad_msg2 db ' . . already exists$'
- end_line db 10,13,'$'
- code_start: ;parse command line into source and target parameters
- mov dx,offset copyright ;display copyright notice
- mov ah,9h
- int 21h
- mov ah,30h ; get pc-dos version
- int 21h
- mov pc_dos_ver,al
- mov si,80h ;psp parameter byte count pointer
- mov cl,[si] ;move byte count to cl
- xor ch,ch ;zero ch
- jcxz no_parms_passed ;if cx is zero, there are no parameters
- mov dx,cx ;save byte count in dx
- inc si ;point to parameter area
- mov di,si ;copy si to di for cleanup routine
- cld ;set direction flag to forward
- clean_parms: ;change valid delimiters to blanks, lower to upper case
- lodsb ;load each character to al
- push di ;save di on stack
- mov di,offset valid_in ;point to table of valid inputs
- push cx ;save cx on stack
- mov cx,valid_num ;set CX TO NUMBER OF INPUTS TO LOOK FOR
- repne scasb ;see if any are in al
- jcxz clean_end ;if not, change nothing
- mov bx,valid_num ;set up bx to point to valid output
- sub bx,cx ;this will leave bx one off
- mov al,valid_out [bx-1] ;load the valid output to al
- clean_end:
- pop cx ;restore cx
- pop di ;restore di
- stosb ;store modified al back to psp
- loop clean_parms ;loop until cx is zero
- mov cx,dx ;restore number of bytes in psp to cx
- mov dx,2 ;set dx to look for up to 2 parameters
- mov bx,offset source_file ;set bx to address of 1st parameter
- mov al,' ' ;set up to scan for first non-blank
- mov di,81h ;set di to pc-dos parameter pointer
- find_parms: ;start looking for parameters, load to program storage
- repe scasb ;scan while blanks
- mov si,di ;set si to second non-blank byte
- dec si ;adjust it to first non-blank byte
- inc cx ;adjust cx to compensate
- jcxz parms_loaded ;if cx is zero, no parameters left
- mov di,bx ;set di to parameter hold area
- mov ax,cx ;store cx to first byte of hold area
- stosb ;di is adjusted to second byte here
- store: lodsb ;load each byte to al
- cmp al,' ' ;is it a blank?
- jz end_store ;yes, end of this parameter
- stosb ;no, store the byte to hold area
- end_store:
- loopnz store ;keep looking
- sub [bx],cx ;store number of bytes in each
- jcxz parms_loaded ;if cx is zero, no more parameters
- dec byte ptr [bx] ;parameter to first byte of hold area
- mov di,si ;set up to scan for next non-blank
- dec di ;adjust di to point to the blank
- inc cx ;adjust cx to compensate
- dec dx ;decrement dx counter
- cmp dx,0 ;is dx zero?
- jz parms_loaded ;yes all expected parameters loaded
- add bx,path_file_len ;no, point to next part of hold area
- jmp find_parms ;go back and look for more
- parms_loaded: ;all parameters are loaded
- cmp source_file[0],0 ;if there are no bytes in the
- ja fix_up ;source_file, no paramters present
- no_parms_passed: ;exit with an error if there are
- mov dx,offset no_parms ;no parameters passed
- jmp error_exit
- fix_up: ;fix source_file and target_path
- mov si,offset source_file ;for search and rename calls
- lodsb ;get number of bytes
- xor ah,ah ;zero ah
- mov di,si ;mov si to di for scan
- add di,ax ;start scan at end of parameter
- dec di ;
- mov cx,ax ;set cx to number of bytes
- mov al,'\' ;scan for the last '\'
- std ;set direction flag to reverse
- repnz scasb ;scan while not '\'
- jnz no_source_dir ;if zero flag not set, '\' not found
- add di,2 ;add 2 to di to point to file name
- jmp source_fixed ;position
- no_source_dir: ;no source directory was specified
- add di,1 ;adjust di
- cmp source_file[2],':' ;check for specified disk drive
- jne source_fixed ;none present, we're done
- mov di,offset source_file[3];yes, set di to point of first byte
- source_fixed: ;after ':'
- mov source_end,di ;move di to source_end pointer
- cld ;set direction flag to forward
- mov si,offset target_path ;set up to look for '\' present
- lodsb ;get number of bytes
- cmp al,0 ;if it's zero, no target specified
- je no_target
- xor ah,ah ;zero ah
- add si,ax ;add it to si to point to end
- dec si ;decrement si to adjust
- lodsb ;look at last byte
- mov di,si ;copy si to di
- cmp al,'\' ;is last byte a '\'?
- je target_fixed ;yes, everything's fine
- cmp target_path[0],2 ;if target_path is 2 bytes long and
- jne store_slash ;is a drive specification,
- cmp target_path[2],':' ;let it default to the current
- je target_fixed ;directory
- store_slash: ;place a '\' at the end of
- mov al,'\' ;target_path if user did not
- stosb
- target_fixed:
- mov target_end,di ;move di to target_end pointer
- jmp find_file
- no_target: ;set up to allow target path default
- mov target_end,offset target_path + 1 ;to current path
- find_file:
- mov dx,offset source_file + 1 ;dx points to source file
- mov ah,4Eh ;request function 4Eh (find first file)
- mov cx,0 ;set cx to zero for normal files only
- int 21h ;call pc-dos
- jnc found_file ;if no error, first file found
- mov dx,offset file_not_found ;if no files found, exit
- jmp error_exit ;program with error message
- found_file:
- mov di,source_end ;di points to end of source path
- mov si,9Eh ;si points to default DTA in psp
- mov cx,13 ;dta will have 13 bytes
- rep movsb ;move bytes to source_file
- mov di,target_end ;di points to end of target path
- mov si,9Eh ;si points to default DTA in psp
- mov cx,13 ;DTA will have 13 bytes
- rep movsb ;move bytes to target_path
- mov dx,offset source_file + 1 ;dx points to old file name
- mov di,offset target_path + 1 ;di points to new file name
- mov ah,56h ;request function 56h (rename file)
- int 21h ;call pc-dos
- jnc good_red ;if no error, call was successful
- cmp ax,3 ;check for error 3 (path not found)
- jne err_5
- mov dx,offset path_not_found
- jmp error_exit ;exit program with error message
- err_5: cmp ax,5 ;check for error 5 (file inaccessible)
- jne err_17
- mov err_flag,1 ;soft error -
- call red_msg ;issue message with subroutine
- jmp next_file ;and keep going
- err_17: cmp ax,17 ;check for error 17 (drive conflict)
- jne undef
- mov dx,offset drives_conflict
- jmp error_exit ;exit program with error message
- undef: mov dx,offset undefined_err ;undefined error from function 56h
- jmp error_exit ;exit program with error message
- good_red:
- mov err_flag,0 ;set error flag off and
- call red_msg ;issure message with subroutine
- next_file: ;look for next file
- mov ah,4Fh ;request function 4fh (find next file)
- mov cx,0
- int 21h
- jnc found_another ;no error, another file was found
- jmp end_ok ;error, we're done finding files
- found_another:
- jmp found_file ;go process next file
- end_ok: int 20h ;exit to pc-dos
-
- error_exit: ;print error message and exit
- push dx ;save error message pointer on stack
- mov ah,9
- mov dx,offset err_head
- int 21h
- mov ah,9
- pop dx
- int 21h
- mov ah,9
- mov dx,offset err_tail
- int 21h
- int 20h ;exit to pc-dos
-
- red_msg proc near ;display message for each file
- mov cx,2 ;2 fields - source & target file
- mov bx,offset source_file + 1 ;point to source file
- start1: mov si,bx ;copy bx to si
- start2: lodsb ;load each byte to al
- cmp al,0 ;if ascii 0 end of field
- je between
- mov dl,al ;copy byte to dl for funtion 2h
- mov ah,2h ;request function 2h
- int 21h ;call pc-dos
- jmp start2 ;get next character
- between:cmp cx,2 ;is it first or second field
- jne cr_lf ;if second, display end of message
- cmp err_flag,0 ;is this a success message?
- jz ok1 ;yes, go to good_msg
- mov dx, offset bad_msg1 ;no, display first part of bad_msg
- mov ah,9h ;request function 9h
- int 21h ;call pc-dos
- jmp next ;go process next field
- ok1: mov dx, offset good_msg ;display good_msg
- mov ah,9h ;request function 9h
- int 21h ;call pc-dos
- jmp next ;go process next field
- cr_lf: cmp err_flag,0 ;is this a success message?
- jz ok2 ;yes, go to terminate message
- mov dx,offset bad_msg2 ;no, display second part of bad_msg
- mov ah,9h ;request function 9h
- int 21h ;call pc-dos
- pc_dos_2: ;patch for incorrect error
- cmp pc_dos_ver,3 ;return in pc_dos 2.0 and 2.1
- jae ok2
- mov dx,offset pc_dos_2_patch
- mov ah,9h
- int 21h
- mov dx,offset path_not_found
- int 21h
- ok2: mov dx,offset end_line ;terminate display line
- mov ah,9h ;request function 9h
- int 21h
- next: add bx,path_file_len ;move bx to point to next field
- loop start1 ;loop for second field
- ret ;or end and return to calling point
- red_msg endp
- red ends
- end begin